<template>
	<el-row :gutter="40">
		<el-col v-if="form.id === ''">
			<el-empty description="请选择左侧菜单后操作" :image-size="100"></el-empty>
		</el-col>
		<template v-else>
			<el-col :lg="12">
				<h2>{{ form.title || "新增菜单" }}</h2>
				<el-form :model="form" :rules="rules" ref="dialogForm" label-width="80px" label-position="left">
					<el-form-item label="显示名称" prop="title">
						<el-input v-model="form.title" clearable placeholder="菜单显示名字"></el-input>
					</el-form-item>
					<el-form-item label="上级菜单" prop="parentId">
						<el-cascader v-model="form.parentId" @change="parentChange" :options="menuOptions"
							:props="menuProps" :show-all-levels="false" placeholder="顶级菜单" clearable></el-cascader>
					</el-form-item>
					<el-form-item label="类型" prop="type">
						<el-radio-group v-model="form.type">
							<el-radio-button value="menu">菜单</el-radio-button>
							<el-radio-button value="iframe">Iframe</el-radio-button>
							<el-radio-button value="link">外链</el-radio-button>
							<el-radio-button value="button">按钮</el-radio-button>
						</el-radio-group>
					</el-form-item>
					<el-form-item label="别名" prop="name">
						<el-input v-model="form.name" clearable placeholder="菜单别名"></el-input>
						<div class="el-form-item-msg">系统唯一且与内置组件名一致，否则导致缓存失效。如类型为Iframe的菜单，别名将代替源地址显示在地址栏</div>
					</el-form-item>
					<el-form-item label="菜单图标" prop="icon">
						<sc-icon-select v-model="form.icon" clearable></sc-icon-select>
					</el-form-item>
					<el-form-item label="路由地址" prop="path">
						<el-input v-model="form.path" clearable placeholder=""></el-input>
					</el-form-item>
					<el-form-item label="重定向" prop="redirect">
						<el-input v-model="form.redirect" clearable placeholder=""></el-input>
					</el-form-item>
					<el-form-item label="菜单高亮" prop="active">
						<el-input v-model="form.active" clearable placeholder=""></el-input>
						<div class="el-form-item-msg">子节点或详情页需要高亮的上级菜单路由地址</div>
					</el-form-item>
					<el-form-item label="视图" prop="component">
						<el-input v-model="form.component" clearable placeholder="">
							<template #prepend>views/</template>
						</el-input>
						<div class="el-form-item-msg">如父节点、链接或Iframe等没有视图的菜单不需要填写</div>
					</el-form-item>
					<el-form-item label="颜色" prop="color">
						<el-color-picker v-model="form.color" :predefine="predefineColors"></el-color-picker>

					</el-form-item>
					<el-form-item label="是否隐藏" prop="hidden">
						<el-checkbox v-model="form.hidden">隐藏菜单</el-checkbox>
						<el-checkbox v-model="form.hiddenBreadcrumb">隐藏面包屑</el-checkbox>
						<div class="el-form-item-msg">菜单不显示在导航中，但用户依然可以访问，例如详情页</div>
					</el-form-item>
					<el-form-item label="整页路由" prop="fullpage">
						<el-switch v-model="form.fullpage" />
					</el-form-item>
					<el-form-item label="标签" prop="tag">
						<el-input v-model="form.tag" clearable placeholder=""></el-input>
					</el-form-item>
					<el-form-item>
						<el-button type="primary" @click="save" :loading="loading">保 存</el-button>
					</el-form-item>
				</el-form>

			</el-col>
			<el-col :lg="12" class="apilist">
				<h2>接口权限</h2>
				<SelectPageTable language="zh-chs" v-model="form.apiIds" :multiple="true" :columns="columns"
					@fetch-data="fetchData" @fetch-selected-data="fetchSelectedData" @selection-change="selectionChange" />
			</el-col>
		</template>
	</el-row>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
import scIconSelect from '@/components/scIconSelect'
import { SelectPageTable } from 'v-selectpage'
import type {
	SelectPageKey, FetchSelectedDataCallback,
	PageParameters, FetchDataCallback, SelectPageTableColumn
} from 'v-selectpage'

export default defineComponent({
	components: {
		scIconSelect,
		SelectPageTable
	},
	props: {
		menu: { type: Object, default: () => { } },
	},
	data() {
		return {
			selected: ref<SelectPageKey[]>([2, 4, 7]),
			columns: ref<SelectPageTableColumn[]>([
				{ title: 'ID', data: 'id' },
				{ title: 'API名称', data: "name" },
				{ title: '请求路径', data: 'path' },
				{ title: '请求方法', data: 'method' },
			]),
			apiObj: this.$API.system.api.list,
			tsValue: {},
			tsProps: {
				label: 'name',
				value: 'name',
				keyword: "keyword"
			},
			apiTree: {},
			value: {},
			form: {
				id: "",
				parentId: "",
				name: "",
				path: "",
				component: "",
				redirect: "",
				title: "",
				icon: "",
				active: "",
				color: "",
				type: "menu",
				fullpage: false,
				tag: "",
				hidden: "",
				hiddenBreadcrumb: "",
				apiIds: [],
				apiList: []
			},
			menuOptions: [],
			menuProps: {
				value: 'id',
				label: 'title',
				checkStrictly: true,
				multiple: false
			},
			predefineColors: [
				'#ff4500',
				'#ff8c00',
				'#ffd700',
				'#67C23A',
				'#00ced1',
				'#409EFF',
				'#c71585'
			],
			rules: {
				'title': [
					{ required: true, message: '请输入显示名称' }
				],
				name: [
					{ required: true, message: '请输入别名' }
				],
				path: [
					{ required: true, message: '请输入路由地址' }
				],
				type: [
					{ required: true, message: '请选择类型' }
				]
			},
			apiListAddTemplate: {
				data: {}
			},
			loading: false
		}
	},
	watch: {
		menu: {
			handler() {
				this.menuOptions = this.treeToMap(this.menu)
			},
			deep: true
		}
	},
	mounted() {
		console.log(this.apiToTree(this.$API))
	},
	methods: {
		async fetchData(data: PageParameters, callback: FetchDataCallback) {
			const { search, pageNumber, pageSize } = data

			// request parameters
			const parameters = {
				search: {
					name: search,
					path: search
				},
				fields: ["id", "name", "path", "method"],
				page: pageNumber,
				pagesize: pageSize
			}
			var res = await this.$API.system.api.list.get(parameters)
			callback(res.data.rows, res.data.total)
		},
		fetchSelectedData(keys: SelectPageKey[], callback: FetchSelectedDataCallback) {
			// get data models by keys
			callback(this.form.apiList)
		},
		selectionChange(items: Record<string, unknown>[]) {
			this.form.apiList = items
		},
		tsChange() {
			console.log(this.form.apiList)
		},
		//简单化菜单
		treeToMap(tree) {
			const map = [
				{
					id: 0,
					parentId: 0,
					title: "顶级菜单"
				}
			]
			tree.forEach(item => {
				var obj = {
					id: item.id,
					parentId: item.parentId,
					title: item.title,
					children: item.children && item.children.length > 0 ? this.treeToMap(item.children) : null
				}
				map.push(obj)
			})
			return map
		},
		apiToTree(api) {
			var arr = []
			Object.keys(api).map(key => {
				var o = api[key]
				if (typeof o != 'object') {
					return
				}
				var a = {
					name: api[key].name,
					url: api[key].url,
					children: []
				}
				if (typeof o == 'object' && o.url === undefined) {
					console.log(o)
					a.children = this.apiToTree(o)
				}
				arr.push(a)
			})
			return arr
		},
		parentChange(value) {
			this.form.parentId = value[0]
		},
		//保存
		async save() {
			this.$refs['dialogForm'].validate(async (valid) => {
				if (valid) {
					this.loading = true
					var res
					if (this.form.id == 0) {
						res = await this.$API.system.menu.add.post(this.form)
					} else {
						res = await this.$API.system.menu.update.put(this.form)
					}
					this.loading = false
					if (res.code == 200) {
						//获取菜单
						var menu = null
						menu = await this.$API.system.menu.myMenus.get()
						if (menu.code == 200) {
							if (menu.data.menu.length == 0) {
								this.islogin = false
								this.$alert("当前用户无任何菜单权限，请联系系统管理员", "无权限访问", {
									type: 'error',
									center: true
								})
								return false
							}
							this.$TOOL.data.set("MENU", this.$TOOL.mapToTree(menu.data.menu, 0, this.$TOOL.menuToRoute))
						}
						this.$message.success("保存成功")
					} else {
						this.$message.warning(res.message)
					}
				} else {
					return false;
				}
			})
		},
		//表单注入数据
		async setData(data, pid) {
			this.loading = true
			var menu
			menu = data
			if (data.id != 0) {
				var res = await this.$API.system.menu.info.get({ id: data.id })
				if (res.code != 200) {
					this.$message.warning(res.message)
					return
				}
				menu.apiList = res.data.apiList
			}
			menu.apiIds = []
			this.form = menu
			if (menu.apiList) {
				menu.apiList.map((v) => {
					this.form.apiIds.push(v.id)
				})
			}
			this.form.parentId = pid
			this.loading = false
		}
	}
})
</script>

<style scoped>
h2 {
	font-size: 17px;
	color: #3c4a54;
	padding: 0 0 30px 0;
}

.apilist {
	border-left: 1px solid #eee;
}

[data-theme="dark"] h2 {
	color: #fff;
}

[data-theme="dark"] .apilist {
	border-color: #434343;
}
</style>
